using Digitalmes.Application.Scada.Commands;
using Digitalmes.Domain;
using Digitalmes.Infrastructure.Scada.Extensions;
using ThingsEdge.Exchange.Contracts;

namespace Digitalmes.Infrastructure.Scada.Handlers;

/// <summary>
/// 产品进站请求处理。
/// </summary>
internal sealed class InboundHandler(ISender sender, ILogger<InboundHandler> logger) : IScadaAskHandler
{
    public async Task<ScadaResult> HandleAsync(RequestMessage message, CancellationToken cancellationToken = default)
    {
        var sn = message.GetString(TagDefinition.PLC_Inbound_Sign);

        // 请求日志
        logger.LogInformation("[进站请求数据] {SN}, 产线：{LineName}，工位：{WsCode}，数据：{Message}",
            sn,
            message.Schema.ChannelName,
            message.Schema.TagGroupName,
            message.Values.Select(s => new { s.TagName, s.Address, s.Value }).ToJson());

        if (string.IsNullOrWhiteSpace(sn))
        {
            return LoggerHelper.LogAndReturn(logger, "进站响应", message.Schema.ChannelName, message.Schema.TagGroupName!, ErrorCode.E1101);
        }

        var productCode = message.GetString(TagDefinition.PLC_Inbound_ProductCode);
        InboundCommand command = new()
        {
            LineCode = message.Schema.ChannelName,
            WsCode = message.Schema.TagGroupName,
            SN = sn,
            ProductCode = productCode,
            Operator = message.GetString(TagDefinition.PLC_Inbound_Operator),
            Shift = message.GetString(TagDefinition.PLC_Inbound_Shift),
            Rfid = message.GetString(TagDefinition.PLC_Inbound_Rfid),
        };

        try
        {
            var result = await sender.Send(command, cancellationToken).ConfigureAwait(false);

            // 响应日志
            logger.LogInformation("[进站响应] {SN}, 产线：{LineName}，工位：{WsCode}，状态: {State}, 消息: [{InnerErrorCode}]-{ErrMessage}; 回调值: {CallbackItems}",
                sn,
                message.Schema.ChannelName,
                message.Schema.TagGroupName,
                result.State.ToString(),
                result.InnerErrorCode.ToString(),
                result.GetErrorMessage(),
                result.CallbackItems.ToJson() ?? "[]");

            return result;
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "[进站服务处理异常] {SN}, 产线：{LineName}，工位：{WsCode}",
                sn,
                message.Schema.ChannelName,
                message.Schema.TagGroupName);
            return ScadaResult.Error();
        }
    }
}
